import { logger } from './logger'

/**
 * Erlang数据解析工具
 * 用于解析从后端返回的Erlang格式数据
 */

/**
 * 解析Erlang二进制字符串 <<num,num,...>> 为普通字符串
 * @param {string} binaryStr - Erlang二进制字符串
 * @returns {string} 解析后的字符串
 */
export function parseErlangBinary(binaryStr: string): string {
  if (!binaryStr || typeof binaryStr !== 'string') {
    return binaryStr
  }
  
  if (!binaryStr.startsWith('<<') || !binaryStr.endsWith('>>')) {
    return binaryStr
  }
  
  try {
    // 提取数字列表
    const numsStr = binaryStr.slice(2, -2)
    if (!numsStr.trim()) {
      return ''
    }
    
    const nums = numsStr.split(',').map(n => parseInt(n.trim())).filter(n => !isNaN(n))
    
    if (nums.length === 0) {
      return binaryStr
    }
    
    // 尝试UTF-8解码（支持中文）
    try {
      const uint8Array = new Uint8Array(nums)
      const decoder = new TextDecoder('utf-8')
      const decoded = decoder.decode(uint8Array)
      
      // 验证解码结果是否有效
      if (decoded && !decoded.includes('\uFFFD')) {
        logger.debug('🔤 [字符解码] UTF-8解码成功:', { 原始: binaryStr, 解码: decoded })
        return decoded
      }
    } catch (utf8Error) {
      logger.warn('UTF-8解码失败，尝试其他方法:', utf8Error)
    }
    
    // 回退到简单的字符码转换
    const result = String.fromCharCode(...nums)
    logger.debug('🔤 [字符解码] 字符码转换:', { 原始: binaryStr, 解码: result })
    return result
    
  } catch (error) {
    logger.warn('❌ [字符解码] 解析Erlang二进制字符串失败:', error, '原始字符串:', binaryStr)
    return binaryStr
  }
}

/**
 * 解析Erlang map格式 #{key => value, ...} 为JavaScript对象
 * @param {string} mapStr - Erlang map字符串
 * @returns {object} 解析后的对象
 */
export function parseErlangMap(mapStr: string): Record<string, any> {
  const result: Record<string, any> = {}
  
  if (!mapStr || typeof mapStr !== 'string') {
    return result
  }
  
  // 移除外层的 #{ 和 }
  let cleanStr = mapStr.trim()
  if (cleanStr.startsWith('#{') && cleanStr.endsWith('}')) {
    cleanStr = cleanStr.slice(2, -1)
  }
  
  try {
    // 使用正则表达式匹配键值对
    const pattern = /(\w+)\s*=>\s*([^,}]+)/g
    let match
    
    while ((match = pattern.exec(cleanStr)) !== null) {
      let key = match[1].trim()
      let value: any = match[2].trim()
      
      // 处理二进制字符串
      if (value.startsWith('<<')) {
        // 找到完整的二进制字符串
        const binaryStart = cleanStr.indexOf(value)
        const binaryEnd = cleanStr.indexOf('>>', binaryStart) + 2
        const binaryPart = cleanStr.slice(binaryStart, binaryEnd)
        value = parseErlangBinary(binaryPart)
      } else if (/^\d+$/.test(value)) {
        // 数字类型
        value = parseInt(value)
      }
      
      result[key] = value
    }
  } catch (error) {
    logger.warn('解析Erlang map失败:', error)
  }
  
  return result
}

/**
 * 解析数据为JavaScript数据结构（支持新的JSON格式和旧的Erlang格式）
 * @param {string|Object} data - 输入数据（可以是JSON对象或Erlang字符串）
 * @returns {Array} 解析后的数据数组
 */
export function parseErlangTerm(data: any): any[] {
  logger.debug('🔍 [数据解析] 源头数据:', data)
  if (!data) {
    logger.warn('⚠️ [数据解析] 输入数据为空')
    return []
  }
  
  logger.debug('🔍 [数据解析] 开始解析数据:', { 
    数据类型: typeof data, 
    是否对象: typeof data === 'object',
    数据预览: typeof data === 'string' ? data.substring(0, 200) + '...' : data
  })
  
  
  try {
    return parseNewJsonFormat(data)
  } catch (error) {
    logger.error('❌ [数据解析] 解析失败:', error)
    return []
  }
}

/**
 * 解析新的JSON格式数据
 * @param {Object} jsonData - JSON格式的数据
 * @returns {Array} 解析后的数据数组
 */
function parseNewJsonFormat(data: any): any[] {
  let jsonData
  
  // 如果data已经是对象，直接使用；否则解析JSON字符串
  if (typeof data === 'object') {
    jsonData = data
  } else {
    jsonData = JSON.parse(data)
  }
  
  logger.debug('🆕 [JSON解析] 开始解析新格式数据:', jsonData)
  const result: any[] = []
  
  try {
    // 检查是否有result数组
    if (jsonData.result && Array.isArray(jsonData.result)) {
      logger.debug(`🔍 [JSON解析] 发现result数组，包含 ${jsonData.result.length} 个服务器`)
      
      // 遍历result数组中的每个服务器数据
      jsonData.result.forEach((serverData: any, index: number) => {
        const standardServerData = {
          platform: serverData.platform?.replace(/"/g, '') || 'unknown', // 移除多余的引号
          zone_id: serverData.zone_id || 0,
          open_time: serverData.srv_open_time || 0,
          camps: serverData.camps || []
        }
        
        result.push(standardServerData)
        
        logger.debug(`✅ [JSON解析] 第${index + 1}个服务器解析成功:`, {
          平台: standardServerData.platform,
          区服ID: standardServerData.zone_id,
          开服时间: new Date(standardServerData.open_time * 1000).toLocaleString('zh-CN'),
          活动数量: standardServerData.camps.length,
          活动列表: standardServerData.camps.slice(0, 3).map((camp: any) => ({
            ID: camp.id,
            名称: camp.name,
            开始: new Date(camp.start_time * 1000).toLocaleDateString('zh-CN'),
            结束: new Date(camp.end_time * 1000).toLocaleDateString('zh-CN')
          })).concat(standardServerData.camps.length > 3 ? [`...还有${standardServerData.camps.length - 3}个活动`] : [])
        })
      })
    } else {
      // 兼容旧格式：直接处理单个服务器数据
      logger.debug('🔄 [JSON解析] 使用兼容模式处理单个服务器数据')
      const standardServerData = {
        platform: jsonData.platform?.replace(/"/g, '') || 'unknown', // 移除多余的引号
        zone_id: jsonData.zone_id || 0,
        open_time: jsonData.srv_open_time || 0,
        camps: jsonData.camps || []
      }
      
      result.push(standardServerData)
      
      logger.debug(`✅ [JSON解析] 单服务器解析成功:`, {
        平台: standardServerData.platform,
        区服ID: standardServerData.zone_id,
        开服时间: new Date(standardServerData.open_time * 1000).toLocaleString('zh-CN'),
        活动数量: standardServerData.camps.length,
        活动列表: standardServerData.camps.slice(0, 3).map((camp: any) => ({
          ID: camp.id,
          名称: camp.name,
          开始: new Date(camp.start_time * 1000).toLocaleDateString('zh-CN'),
          结束: new Date(camp.end_time * 1000).toLocaleDateString('zh-CN')
        })).concat(standardServerData.camps.length > 3 ? [`...还有${standardServerData.camps.length - 3}个活动`] : [])
      })
    }
    
    logger.debug(`🎯 [JSON解析] 总计解析完成: ${result.length} 个服务器，${result.reduce((sum, server) => sum + server.camps.length, 0)} 个活动`)
    
  } catch (error) {
    logger.error('❌ [JSON解析] 解析失败:', error)
  }
  
  return result
}

/**
 * 将解析后的数据转换为活动列表格式
 * @param {Array} parsedData - 解析后的服务器数据
 * @returns {Array} 活动列表
 */
export function convertToCampList(parsedData: any[]): any[] {
  logger.debug('🔄 [数据转换] 开始转换活动列表:', { 
    输入数据类型: typeof parsedData, 
    是否数组: Array.isArray(parsedData), 
    数据长度: parsedData?.length,
    数据内容: parsedData
  })
  
  const campList: any[] = []
  
  if (!Array.isArray(parsedData)) {
    logger.warn('⚠️ [数据转换] 输入数据不是数组，返回空列表')
    return campList
  }
  
  for (const [serverIndex, serverData] of parsedData.entries()) {
    logger.debug(`📊 [数据转换] 处理服务器 ${serverIndex}:`, serverData)
    
    const platform = serverData.platform || ''
    const zoneId = serverData.zone_id || ''
    const camps = serverData.camps || []
    
    const serverKey = `${platform}_${zoneId}`
    logger.debug(`🏷️ [数据转换] 服务器标识: ${serverKey}, 活动数量: ${camps.length}`)
    
    for (const [campIndex, camp] of camps.entries()) {
      if (camp && typeof camp === 'object') {
        // 处理新格式的活动数据
        const campItem = {
          server: serverKey,
          camp_id: camp.id || camp.camp_id || 'N/A',
          camp_name: camp.name || camp.camp_name || '未知活动',
          start_time: camp.start_time || 0,
          end_time: camp.end_time || 0,
          sec_type: camp.sec_type || 0
        }
        
        // 验证时间戳是否合理
        if (campItem.start_time > 0 && campItem.end_time > 0 && campItem.end_time > campItem.start_time) {
          logger.debug(`🎯 [数据转换] 活动 ${campIndex}:`, {
            服务器: campItem.server,
            活动ID: campItem.camp_id,
            活动名称: campItem.camp_name,
            开始时间: new Date(campItem.start_time * 1000).toLocaleString('zh-CN'),
            结束时间: new Date(campItem.end_time * 1000).toLocaleString('zh-CN'),
            持续天数: Math.ceil((campItem.end_time - campItem.start_time) / 86400),
            活动类型: campItem.sec_type
          })
          
          campList.push(campItem)
        } else {
          logger.warn(`⚠️ [数据转换] 跳过时间无效的活动:`, {
            活动名称: campItem.camp_name,
            开始时间: campItem.start_time,
            结束时间: campItem.end_time
          })
        }
      } else {
        logger.warn(`⚠️ [数据转换] 跳过无效活动数据:`, camp)
      }
    }
  }
  
  // 按服务器和开始时间排序
  campList.sort((a, b) => {
    if (a.server !== b.server) {
      return a.server.localeCompare(b.server)
    }
    return a.start_time - b.start_time
  })
  
  logger.debug(`✅ [数据转换] 转换完成，总共 ${campList.length} 个活动`)
  logger.debug(`📈 [数据转换] 服务器分布:`, campList.reduce((acc, camp) => {
    acc[camp.server] = (acc[camp.server] || 0) + 1
    return acc
  }, {}))
  
  return campList
}

/**
 * 生成活动颜色映射
 * @param {Array} campData - 活动数据
 * @returns {Object} 颜色映射对象
 */
export function generateCampColorMap(campData: any[]): Record<string, string> {
  // 暗黑主题友好的颜色方案
  const colorPalette = [
    '#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F',
    '#BB8FCE', '#85C1E2', '#F8B739', '#52B788', '#E74C3C', '#3498DB',
    '#9B59B6', '#E67E22', '#1ABC9C', '#F39C12', '#D35400', '#C0392B',
    '#16A085', '#27AE60', '#2980B9', '#8E44AD', '#2C3E50', '#F1C40F'
  ]
  
  // 收集所有唯一的活动名称
  const uniqueCampNames = new Set<string>()
  campData.forEach(camp => {
    const campName = camp.camp_name || '未知活动'
    uniqueCampNames.add(campName)
  })
  
  // 为每个活动名称分配颜色
  const campColorMap: Record<string, string> = {}
  const sortedCampNames = Array.from(uniqueCampNames).sort()
  
  sortedCampNames.forEach((campName, index) => {
    campColorMap[campName] = colorPalette[index % colorPalette.length]
  })
  
  return campColorMap
}

/**
 * 合并连续的同名活动
 * @param {Array} camps - 某个服务器的活动列表
 * @returns {Array} 合并后的活动列表
 */
export function mergeContinuousActivities(camps: any[]): any[] {
  if (!Array.isArray(camps) || camps.length === 0) {
    return []
  }
  
  // 按活动名称和开始时间排序
  const sortedCamps = [...camps].sort((a, b) => {
    const nameCompare = (a.camp_name || '').localeCompare(b.camp_name || '')
    if (nameCompare !== 0) return nameCompare
    return (a.start_time || 0) - (b.start_time || 0)
  })
  
  const mergedCamps: any[] = []
  let currentGroup: any = null
  
  for (const camp of sortedCamps) {
    const campName = camp.camp_name || ''
    const startTime = camp.start_time || 0
    const endTime = camp.end_time || 0
    
    if (!currentGroup || currentGroup.camp_name !== campName) {
      // 开始新的活动组
      currentGroup = {
        ...camp,
        original_camps: [camp] // 保存原始活动信息用于调试
      }
      mergedCamps.push(currentGroup)
    } else {
      // 检查是否可以与当前组合并（时间连续或重叠）
      const timeDiff = startTime - currentGroup.end_time
      const isConnectable = timeDiff <= 86400 // 允许1天的间隔
      
      if (isConnectable) {
        // 合并到当前组
        currentGroup.end_time = Math.max(currentGroup.end_time, endTime)
        currentGroup.original_camps.push(camp)
        
        logger.debug(`🔗 [活动合并] 合并活动: ${campName}`, {
          原始时间段: `${formatTimestamp(startTime)} - ${formatTimestamp(endTime)}`,
          合并后时间段: `${formatTimestamp(currentGroup.start_time)} - ${formatTimestamp(currentGroup.end_time)}`,
          时间间隔: `${Math.round(timeDiff / 86400)}天`
        })
      } else {
        // 时间间隔太大，开始新组
        currentGroup = {
          ...camp,
          original_camps: [camp]
        }
        mergedCamps.push(currentGroup)
        
        logger.debug(`🆕 [活动合并] 新建活动组: ${campName}`, {
          时间段: `${formatTimestamp(startTime)} - ${formatTimestamp(endTime)}`,
          与上一组间隔: `${Math.round(timeDiff / 86400)}天`
        })
      }
    }
  }
  
  logger.debug(`✅ [活动合并] 合并完成: ${camps.length} -> ${mergedCamps.length}`, {
    原始活动: camps.length,
    合并后活动: mergedCamps.length,
    合并详情: mergedCamps.map(camp => ({
      名称: camp.camp_name,
      时间段: `${formatTimestamp(camp.start_time)} - ${formatTimestamp(camp.end_time)}`,
      原始活动数: camp.original_camps.length
    }))
  })
  
  return mergedCamps
}

/**
 * 计算活动的层级分配（避免时间重叠）
 * @param {Array} camps - 某个服务器的活动列表
 * @returns {Array} 带有层级信息的活动列表 [{camp, layer}, ...]
 */
export function calculateCampLayers(camps: any[]): Array<{camp: any, layer: number}> {
  if (!Array.isArray(camps) || camps.length === 0) {
    return []
  }
  
  // 先合并连续的同名活动
  const mergedCamps = mergeContinuousActivities(camps)
  
  // 按开始时间排序
  const sortedCamps = [...mergedCamps].sort((a, b) => 
    (a.start_time || 0) - (b.start_time || 0)
  )
  
  const campWithLayers: Array<{camp: any, layer: number}> = []
  const layerEndTimes: number[] = [] // 每一层的最后结束时间
  
  for (const camp of sortedCamps) {
    const startTime = camp.start_time || 0
    const endTime = camp.end_time || 0
    
    // 找到第一个不冲突的层级
    let assignedLayer: number | null = null
    
    for (let layerIndex = 0; layerIndex < layerEndTimes.length; layerIndex++) {
      if (startTime >= layerEndTimes[layerIndex]) {
        // 可以放在这一层
        assignedLayer = layerIndex
        layerEndTimes[layerIndex] = endTime
        break
      }
    }
    
    // 如果没找到可用层，创建新层
    if (assignedLayer === null) {
      assignedLayer = layerEndTimes.length
      layerEndTimes.push(endTime)
    }
    
    campWithLayers.push({ camp, layer: assignedLayer })
  }
  
  return campWithLayers
}

/**
 * 格式化时间戳为可读字符串
 * @param {number} timestamp - 时间戳（秒）
 * @param {string} format - 格式类型 ('date', 'datetime', 'short')
 * @returns {string} 格式化后的时间字符串
 */
export function formatTimestamp(timestamp: number, format: string = 'date'): string {
  if (!timestamp || timestamp === 0) {
    return '未知'
  }
  
  try {
    const date = new Date(timestamp * 1000)
    
    switch (format) {
      case 'date':
        return date.toLocaleDateString('zh-CN')
      case 'datetime':
        return date.toLocaleString('zh-CN')
      case 'short':
        return date.toLocaleDateString('zh-CN', {
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit'
        })
      default:
        return date.toLocaleDateString('zh-CN')
    }
  } catch (error) {
    logger.warn('格式化时间戳失败:', error)
    return '无效时间'
  }
}
